package com.xiaode.controller.app.mbit;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.jfinal.aop.Before;
import com.jfinal.kit.Kv;
import com.jfinal.kit.Ret;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.jfinal.plugin.redis.Cache;
import com.jfinal.plugin.redis.Redis;
import com.xiaode.common.constant.Const;
import com.xiaode.common.model.Admin;
import com.xiaode.common.model.MbtiComment;
import com.xiaode.common.model.MbtiPerson;
import com.xiaode.common.model.MbtiPersonality;
import com.xiaode.common.model.MbtiProgress;
import com.xiaode.common.model.MbtiQuestion;
import com.xiaode.common.model.Student;
import com.xiaode.common.model.dto.mbti.MbtiInfoDTO;
import com.xiaode.exce.EnumError;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class MbtiService {
    /**
     * 查询mbti人格
     *
     * @param type
     * @param name
     * @return
     * @throws Exception
     */
    public Ret findMbtiPersonality(String type, String name) throws Exception {
        Kv kv = Kv.create().setIfNotNull("type", type).setIfNotNull("name", name);
        List<Record> list = Db.template("findMbtiPersonality", kv).find();
        return Ret.ok("mbtiPersonality", list);
    }

    /**
     * 查询我的进度
     *
     * @param user
     * @return
     */
    public Ret findProgress(Integer userId, Integer userType) throws Exception {
        //查询我的进度
        MbtiProgress mbtiProgress = MbtiProgress.dao.findFirst("SELECT * FROM mbti_progress WHERE userId = ? AND userType = ?", userId, userType);
        //如果进度不为空并且进度的结果字段不为空,代表已经完成测试
        if (BeanUtil.isNotEmpty(mbtiProgress) && mbtiProgress.getPersonalityId() != null) {
            //查询结果人格
            MbtiPersonality mbtiPersonality = MbtiPersonality.dao.findById(mbtiProgress.getPersonalityId());
            List<MbtiPerson> mbtiPeople = MbtiPerson.dao.find("SELECT * FROM mbti_person WHERE personality_id = ?", mbtiPersonality.getId());
            Integer sum = Db.queryInt("SELECT COUNT(*) FROM mbti_progress");
            return Ret.ok().set("myProgress", mbtiProgress).set("mbtiPersonality", mbtiPersonality).set("person", mbtiPeople).set("num", sum);
        }
        return Ret.ok().set("myProgress", mbtiProgress);
    }

    /**
     * 保存我的进度
     *
     * @param user
     * @param progress
     * @return
     */
    @Before(Tx.class)
    public Ret saveProgress(Integer userId, Integer userType, String progress) throws Exception {
        //查看答题进度
        MbtiProgress mbtiProgress = MbtiProgress.dao.findFirst("SELECT * FROM mbti_progress WHERE userId = ? AND userType = ?", userId, userType);
        if (BeanUtil.isEmpty(mbtiProgress)) {
            mbtiProgress = new MbtiProgress();
            mbtiProgress.setUserId(userId);
            mbtiProgress.setUserType(userType);
            mbtiProgress.save();
        }
        List<MbtiInfoDTO> resList;
        try {
           resList = JSONUtil.toList(progress, MbtiInfoDTO.class);
        }catch (Exception e){
            return Ret.fail().set("error",EnumError.PARAMETER_ERROR.getObj());
        }
        mbtiProgress.setProgress(progress);
        List<MbtiQuestion> all = MbtiQuestion.dao.findAll();
        Map<Integer, MbtiQuestion> map = all.stream().collect(Collectors.toMap(MbtiQuestion::getId, mbtiQuestion -> mbtiQuestion));
        HashMap<Integer, Integer> hashMap = new HashMap<>();
        //统计题目类型
        all.stream().forEach(mbtiQuestion -> {
            Integer type = mbtiQuestion.getType();
            Integer integer = hashMap.get(type);
            if (integer == null) {
                hashMap.put(type, 1);
            } else {
                hashMap.put(type, integer + 1);
            }
        });
        for (MbtiInfoDTO mbtiInfoDTO : resList) {
            //判断当前题目是否是存在的题目
            MbtiQuestion mbtiQuestion = map.get(mbtiInfoDTO.getId());
            if (BeanUtil.isEmpty(mbtiQuestion)) {
                return Ret.fail().set("error", EnumError.MBTI_NOT_EXIST_SUCH_QUESTION.getObj());
            }
            hashMap.put(mbtiQuestion.getType(), hashMap.get(mbtiQuestion.getType()) - 1);
        }
        //答题结束
        if (resList.size() == all.size()) {
            // 统计结果,返回对应人格类型
            Kv kv = staticsMbtiRes(resList, map);
            String error = kv.getStr("error");
            if (StrUtil.isNotEmpty(error)) {
                return Ret.fail().set("error", EnumError.MBTI_NOT_EXIST_SUCH_QUESTION.getObj());
            }
            String mbtiPersonalityType = kv.getStr("res");
            @SuppressWarnings("unchecked")
			Map<String, Integer> resCount = (Map<String, Integer>) kv.get("resCount");
            String s = JSONUtil.toJsonStr(resCount);
            mbtiProgress.setResCount(s);
            //查询当前人格
            MbtiPersonality mbtiPersonality = MbtiPersonality.dao.findFirst("SELECT * FROM mbti_personality WHERE type = ?", mbtiPersonalityType);
            if (BeanUtil.isEmpty(mbtiPersonality)) {
                return Ret.fail().set("error", EnumError.MBTI_PERSONALITY_NOT_EXIST.getObj());
            }
            mbtiProgress.setPersonalityId(mbtiPersonality.getId());
            mbtiProgress.update();
            List<MbtiPerson> mbtiPeople = MbtiPerson.dao.find("SELECT * FROM mbti_person WHERE personality_id = ?", mbtiPersonality.getId());
            Integer sum = Db.queryInt("SELECT COUNT(*) FROM mbti_progress");
            
            return Ret.ok("mbtiPersonality", mbtiPersonality).set("resCount", s).set("person", mbtiPeople).set("num", sum);
        }
        mbtiProgress.update();
        
        return Ret.ok();
    }

    /**
     * 查询问题
     *
     * @return
     */
    public Ret findQuestion(Integer type) {
        List<MbtiQuestion> all = MbtiQuestion.dao.find("SELECT id,question,answer1,answer2,type FROM mbti_question ORDER BY type DESC");
        int i = 0, j = 0;
        for (MbtiQuestion mbtiQuestion : all) {
            if (mbtiQuestion.getType() == 1) {
                i++;
            } else {
                j++;
            }
        }
        if (type != null) {
            all = all.stream().filter(mbtiQuestion -> mbtiQuestion.getType().equals(type)).collect(Collectors.toList());
        }
        return Ret.ok().set("questions", all).set("basicNum", j).set("describeNum", i);
    }

    /**
     * 查询评论
     *
     * @param page
     * @param limit
     * @return
     */
    public Ret findMbtiComments(Integer page, Integer limit) throws Exception {
        Cache redis = Redis.use();
        List<MbtiPersonality> all = MbtiPersonality.dao.findAll();
        Map<Integer, MbtiPersonality> map = all.stream().collect(Collectors.toMap(MbtiPersonality::getId, mbtiPersonality -> mbtiPersonality));
        Page<MbtiComment> commentPage = MbtiComment.dao.paginate(page, limit, "SELECT * ", " FROM mbti_comment ORDER BY id DESC");
        commentPage.getList().stream().forEach(mbtiComment -> {
            if (mbtiComment.getUserType() == 1) {
                Student o = redis.get(Const.user.Student + mbtiComment.getUserId());
                mbtiComment.put("name", o.getName());
                mbtiComment.put("sex", o.getSex());
                mbtiComment.put("pic", o.getAvatarUrl());
            } else {
                Admin o = redis.get(Const.user.Admin + mbtiComment.getUserId());
                mbtiComment.put("name", o.getName());
                mbtiComment.put("sex", o.getGender());
                mbtiComment.put("pic", o.getAvatarUrl());
            }
            MbtiPersonality mbtiPersonality = map.get(mbtiComment.getPersonalityId());
            mbtiComment.put("type", mbtiPersonality.getType());
            mbtiComment.put("personalityName", mbtiPersonality.getName());
        });
        return Ret.ok().set("comments", commentPage);
    }

    /**
     * 发表评论
     *
     * @param user
     * @param content
     * @return
     */
    public Ret mbtiComment(Integer userId, Integer userType, String content) {
        //查询当前用户题目是否答完
        MbtiProgress progresse = MbtiProgress.dao.findFirst("SELECT * FROM mbti_progress WHERE userId = ? AND userType = ?", userId, userType);
        if (BeanUtil.isEmpty(progresse) || progresse.getPersonalityId() == null) {
            return Ret.fail().set("error", EnumError.MBTI_NOT_COMPLETE.getObj());
        }
        //保存评论
        MbtiComment mbtiComment = new MbtiComment();
        mbtiComment.setUserId(userId);
        mbtiComment.setUserType(userType);
        mbtiComment.setContent(content);
        mbtiComment.setPersonalityId(progresse.getPersonalityId());
        mbtiComment.save();
        return Ret.ok();
    }

    /**
     * 删除评论
     *
     * @param user
     * @param commentId
     * @return
     */
    public Ret delMbtiComment(Integer userId, Integer userType, Integer commentId) {
        MbtiComment mbtiComment = MbtiComment.dao.findById(commentId);
        //判断当前评论是否存在
        if (BeanUtil.isEmpty(mbtiComment)) {
            return Ret.fail().set("error", EnumError.COMMENTS_HAS_NOT_EXIT.getObj());
        }
        //判断当前评论是否由该用户发送
        if (mbtiComment.getUserId() != userId || mbtiComment.getUserType() != userType) {
            return Ret.fail().set("error", EnumError.CMMENTS_NOT_BELONE_TO_YOU.getObj());
        }
        mbtiComment.delete();
        return Ret.ok();
    }


    /**
     * 统计结果
     *
     * @param resList
     * @return
     */
    public Kv staticsMbtiRes(List<MbtiInfoDTO> resList, Map<Integer, MbtiQuestion> questionMap) {
        HashMap<String, Integer> map = new HashMap<>();
        map.put("E", 0);
        map.put("I", 0);
        map.put("S", 0);
        map.put("N", 0);
        map.put("T", 0);
        map.put("F", 0);
        map.put("J", 0);
        map.put("P", 0);

        for (MbtiInfoDTO mbtiInfoDTO : resList) {
            int id = mbtiInfoDTO.getId();
            int answer = mbtiInfoDTO.getChoice();
            MbtiQuestion mbtiQuestion = questionMap.get(id);
            String str = mbtiQuestion.getStr("answerType" + answer);
            map.put(str, map.get(str) + 1);
        }

        String res = "";
        res += map.get("E") > map.get("I") ? "E" : "I";
        res += map.get("S") > map.get("N") ? "S" : "N";
        res += map.get("T") > map.get("F") ? "T" : "F";
        res += map.get("J") > map.get("P") ? "J" : "P";
        Kv kv = Kv.create();
        kv.set("res", res).set("resCount", map);
        return kv;
    }

    /**
     * 查询题目数量
     *
     * @return
     */
    public Ret findQuestionNum() {
        List<MbtiQuestion> all = MbtiQuestion.dao.find("SELECT id,type FROM mbti_question ORDER BY type");
        int i = 0, j = 0;
        for (MbtiQuestion mbtiQuestion : all) {
            if (mbtiQuestion.getType() == 1) {
                i++;
            } else {
                j++;
            }
        }
        Integer sum = Db.queryInt("SELECT COUNT(*) FROM mbti_progress");
        return Ret.ok().set("basicNum", j).set("describeNum", i).set("num",sum);
    }
}
